/*---------------------------------------------------------------------------
 *-Version :0.1 @ 08/20/2008  modifed @ 08/30/2008                          *
 *-Auther : Chen Ju                                                         *
 *-Auther Email: sammy105@gmail.com                                         *
 *-Auther site : http://www.kylogs.com/blog                                 * 
 *-This file define all list functions                                      * 
 *-related funcitons.                                                       * 
 *---------------------------------------------------------------------------
 */

/* list functions */
#include <stdlib.h>
#include "easyc_ds.h"
c_linkedlist linkedlist_make(){
    c_linkedlist s;
    s.size=0;
    s.head=NULL;/* it's necessary */
    s.find=easyc_list_find;
    s.contains=easyc_list_contains;
    s.insert=easyc_list_insert;
    s.append=easyc_list_append;
    s.remove=easyc_list_remove;
    return s;
}
c_list *easyc_list_find(eType e,const c_linkedlist * t){
   c_list *l;
   l=t->head;
   if(l==NULL) return NULL;   
   while(l!=NULL){
   	 if(e==l->element) {
   	  break; 
   	}
        l=l->next;
    }
    return l;
}
/* if found returns -1 else returns 1 */
int easyc_list_contains(eType e, const struct easyc_linkedlist * t){
    c_list *l;
    l=t->head;
    while(l!=NULL){
        if(e==l->element) {
           break; /* element found */
        }
        
        l=l->next;
    }
    if(l==NULL) return -1;
    return 1;
}

void easyc_list_insert(eType e,const c_list * li,struct easyc_linkedlist * t){
    c_list * l;
    c_list * ins;
    c_list * temp;
    l=t->head;
    while(l!=NULL){
        if(l==li){
            ins=(c_list *)malloc(sizeof(c_list));
            ins->element=e;
            ins->pre=NULL;
            ins->next=NULL;
            if(l->next==NULL) {
                l->next=ins;
                ins->next=NULL;
                ins->pre=l;
                break;
            }else{
                temp=l->next;
                l->next=ins;
                ins->next=temp;
                ins->pre=l;
                temp->pre=ins;
                break;
            }                        
        }
    }
    return;
}

void easyc_list_append(eType e,struct easyc_linkedlist * t){
    c_list * l;
    c_list * ins;
    c_list * temp;    
    ins=(c_list *)malloc(sizeof(c_list));
    ins->element=e;
    ins->pre=NULL;
    ins->next=NULL;
    l=t->head;
    if(l==NULL){
        t->head=ins;
    }else{
        temp=t->head;
        t->head=ins;
        ins->next=temp;
        temp->pre=ins;        
    }
    return;   
}
void easyc_list_remove(c_list * r,c_linkedlist * t){
    c_list * temp=r;
    if(temp->next==NULL){
        if(r->pre==NULL) {
            t->head=NULL;
            free(temp);
        }else{
            r->pre->next=NULL; 
            free(temp);           
        }
    }
    else{
        if(r->pre==NULL){
            t->head=r->next;
            t->head->pre=NULL;
            free(r);            
        }else{
            r->pre->next=r->next;
            r->next->pre=r->pre;
            free(r);
        }
    }
}
